Blog

BoxLang 1.0.0 Beta 9 Launched

Luis Majano August 09, 2024

Spread the word

Luis Majano

August 09, 2024

Spread the word


Share your thoughts

We are pleased to announce the release of BoxLang 1.0.0-Beta 9! BoxLang Betas are released weekly. This is our ninth marker and we are incredibly excited as we are coming close to our stable release. We have some great news in this release!

What is BoxLang?

BoxLang is a modern dynamic JVM language that can be deployed on multiple runtimes: operating system (Windows/Mac/*nix/Embedded), web server, lambda, iOS, android, web assembly, and more. BoxLang combines many features from different programming languages, including Java, ColdFusion, Python, Ruby, Go, and PHP, to provide developers with a modern and expressive syntax.

It is also a drop-in replacement for Adobe ColdFusion and Lucee Engines.

How to get started?

Visit our docs at https://boxlang.ortusbooks.com and get coding today. If you want to try it out on the web then go to our online REPL at https://try.boxlang.io. You can also checkout our YouTube playlist: https://www.youtube.com/playlist?list=PLNE-ZbNnndB-40LvAbeSeT2Oi3V2gm_B8

Release Notes

Here are the latest release notes: https://boxlang.ortusbooks.com/readme/release-history/1.0.0-beta-9

New Features

BL-105 PDF Module

PDFs have landed for BoxLang. The full implementation for creating PDF documents is now complete and available via our bx-pdf module. This module contributes the following Components to the language:

  • document - the wrapping component for creating PDF documents
    • The following attributes are available to the document component
      • format - The format of the document to generate. This attribute is unused and will be removed in a future release as only PDF generation is supported. Any other format requested will throw an error.
      • encryption - The encryption level to use for the document. Default is none. Possible values are 128-bit, 40-bit, none
      • localUrl - If true, the document will be generated with local URLs. Default is false
      • variable - The name of the variable to store the generated PDF binary
      • backgroundVisible - If true, the background will be visible. Default is true
      • bookmark - If true, bookmarks will be generated. Default is true
      • htmlBookmark - If true, it is possible to convert outlines to a list of named anchors (<a name="anchor_id">label</a>) or a headings structure ( <h1>... <h6> ). Transforming of HTML hyperlinks to PDF hyperlinks (if not explicitly disabled Hyperlink jumps within the same document are supported as well
      • orientation - The orientation of the document. Default is portrait. Possible values are portrait, landscape
      • scale - The percentage to scale the document. Must be less than 100
      • marginBottom - The bottom margin of the document
      • marginLeft - The left margin of the document
      • marginRight - The right margin of the document
      • marginTop - The top margin of the document
      • pageWidth - The width of the page in inches
      • pageHeight - The height of the page in inches
      • fontEmbed - If true, fonts will be embedded in the document. Default is true
      • fontDirectory - The directory where fonts are located
      • openpassword - The password to open protected documents
      • ownerPassword - The password to access restricted permissions
      • pageType - The type of page to generate. Default is A4.
      • pdfa - If true, the document will be generated as a PDF/A document. Default is false
      • filename - The filename to write the PDF to. If not provided and a variable argument is not provided, the PDF will be written to the browser ( Web-context only )
      • overwrite - If true, the file will be overwritten if it exists. Default is false
      • saveAsName - The name to save the PDF as in the browser
      • src - A full URL or path relative to the web root of the source
      • srcfile - The absolute path to a source file
      • mimeType - The mime type of the source. Default is text/html. Possible values are text/html, text/plain, application/xml, image/jpeg, image/png, image/bmp, image/gif
      • unit - The unit of measurement to use. Default is inches. Possible values are in, cm
    • The following attributes are not currently implemented and will throw an error if used
      • permissions - Granular permissability is not yet supported
      • permissionspassword - Granular permissability is not yet supported
      • userPassword - Granular permissability is not yet supported
      • authPassword - Granular permissability is not yet supported
      • authUser - Granular permissability is not yet supported
      • userAgent - HTTP user agent identifier
      • proxyHost - IP address or server name for proxy host
      • proxyPassword - password for the proxy host
      • proxyPort - port of the proxy host
      • proxyUser - user name for the proxy host
      • tagged - yes|no ACF OpenOffice integration not supported
      • formfields - yes|no Form field attributes are not implemented in standard module
      • formsType - FDF|PDF|HTML|XML Form field attributes are not implemented in standard module
  • documentitem - specifies header, footer, and pagebreaks within a document body or documentsection
    • The following attributes are available to the documentitem component
      • type A string which dictates the type of item. Accepted values are pagebreak|header|footer
      • evalAtPrint This attribute is deprecated as all content is evaluated when the body of the tag is processed
  • documentsection - Divides a PDF document into sections. Used in conjunction with a documentitem component, each section can have unique headers, footers, and page numbers. A page break will always precede a section
    • The following attributes are available to the documentsection component
      • marginBottom - The bottom margin of the section in the unit specified in the document component.
      • marginLeft - The left margin of the section in the unit specified in the document component.
      • marginRight - The right margin of the section in the unit specified in the document component.
      • marginTop - The top margin of the section in the unit specified in the document component.
      • mimeType - The mime type of the content. If the content is a file, the mime type is determined by the file extension. If the content is a URL, the mime type is determined by the HTTP response.
      • name - The name of the section. This is used as a bookmark for the section.
      • srcfile - The absolute path of the file to include in the section.
      • src - The URL or path relative to the web root of the content to include in the section.
    • The following attributes are not currently implemented and will throw an error if used
      • userAgent - The HTTP user agent identifier to use when fetching the content from a URL.
      • authPassword - The authentication password to use when fetching the content from a URL.
      • authUser - The authentication user name to use when fetching the content from a URL.

Examples

Simple example using tag-based syntax to generate a physical file:

<bx:set testImage = "https://ortus-public.s3.amazonaws.com/logos/ortus-medium.jpg"/>
<bx:document format="pdf" filename="/path/to/mydocument.pdf">
    <!--- Header for all sections --->
    <bx:documentitem type="header">
        <h1>This is my Header</h1>
    </bx:documentitem>
    <!--- Footer for all sections --->
    <bx:documentitem type="footer">
        <h1>This is My Footer</h1>
        <bx:output><p>Page #bxdocument.currentpagenumber# of #bxdocument.totalpages#</p></bx:output>
    </bx:documentitem>
    <!--- Document section, which will be bookmarked as "Section 1" --->
    <bx:documentsection name="Section 1">
        <h1>Section 1</h1>
    </bx:documentsection>
    <!--- Document section, which will be bookmarked as "Section 2" --->
    <bx:documentsection name="Section 2">
        <h1>Section 2</h1>
    </bx:documentsection>
    <!--- Document section, which contains an image --->
    <bx:documentsection src="#testImage#">
</bx:document>

Example using script syntax to create a variable containing the binary contents of the PDF, which is then written to a file

document format="pdf" variable="myPDF"{
    documentsection name="Section 1"{
        writeOutput("<h1>Section 1</h1>");
        include "/path/to/section1.bxm";
    }
    documentsection name="Section 2"{
        writeOutput("<h1>Section 2</h1>");
        include "/path/to/section2.bxm";
    }
}

fileWrite( "/path/to/mydocument.pdf", myPDF );

BL-110 objectLoad() and objectSave() implemented and renamed to objectSerialize() and objectDeserialize()

This is a really step forward for BoxLang in providing the ability to serialize and deserialize any BoxLang type and any BoxLang class to binary recursively n-levels deep. We have introduced two BIFS to accomplish this:

  • objectSerialize( object, [filepath] ) : binary
  • objectDeserialize( input ) : object

You can pass ANY object to the serialize function and it will recursively try to serialize the object to binary data. You can then store that in a database, cluster, cache, or a file using the filepath argument. To deserialize you can use the objectDeserialize() function and you can pass in the direct binary or a file path location for the binary.

The only requirement is that the object be a BoxLang type or any Java type that implements serializable.

Also note that for CFML compatibility, the compat module will expose them as objectLoad() and objectSave().

BL-420 Exit REPL with quit or exit

You can now exit the BoxLang REPL by typing quit or exit.

> quit

> exit

BL-422 Ability to serialize BoxLang classes to binary and deserialize them back using it's state

This was related to BL-110 but specifically to BoxLang classes. This allows us now to be able to take the state of any BoxLang class and be able to serialize it to binary. You can then deserialize the binary and inflate it back to a BoxLang object graph again.

BL-423 New experimental features block on the `boxlang.json`

The boxlang.json get's a new top level configuration key: experimental which will be a feature flags approach to turn on/off experimental features in BoxLang.

"experimental" : {
    "flag1" : true|false
}

BL-424 BoxRunner action commands now for: compile, cftranspile, featureAudit

We have consolidated our CLI tooling to all funnel through the boxlang binary script or boxlang.bat for windows. You can now execute our CLI tools via action commands which is based on the following keys:

  • compile - Executes the BoxLang compiler tool
  • cftranspile - Executes the CF to BoxLang transpile tool
  • featureAudit - Executes the feature audit tool
boxlang compile <options>
boxlang cftranspile <options>
boxlang featureAudit <options>

Improvements

BL-414 Renaming of Box Cache functions to standardized cache{function}()

The BoxLang Cache BIFs have been renamed to be standardized to the following:

  • cache( [provider:default] )
  • cacheFilter()
  • cacheNames()
  • cacheProviders()
  • cacheService()

BL-415 Increase precision of math operations by using BigDecimal

This introduces BigDecimal usage all over BoxLang for two main use cases:

  • Being able to store and process very large numbers that wouldn't fit inside a Long or a Double like 111111111111111111111111111 + 222222222222222222222222222
  • Being able to retain precision for decimals-- even small ones. For ex: (0.1 + 0.2).toString() outputs 0.30000000000000004 in Lucee 5 and ACF 2023. But in Lucee 6 and BoxLang, it correctly returns .3 without any special work

Not ALL numbers are a BigDecimal-- just the ones that need to be:

  • integer literals in your source code less than 11 chars will be a java Integer
  • integer literals in your source code less than 20 chars will be a java Long
  • All other integer literals in your source will be a java BigDecimal
  • All decimal literals in your source will be a java BigDecimal

Furthermore, we have added a new NumberCaster which we should be using as our primary caster that returns an instance implementing the Number interface in Java

  • any recognizable classes like int, long, double, big decimal, etc are just returned directly
  • Any strings which contain integers (no decimal or sci notation) follow the same rules above (integer for small ones, long for bigger ones, big decimal for really big ones)
  • Any strings with a decimal or sci notation will be made a BigDecimal

Basically, we return the "Smallest" data type we can without losing any precision. (An Integer is about 24 Bytes and a BigDecimal is about 64 Bytes so it seemed worth optimizing a bit)

BL-421 Finalize FileUpload, FileUploadAll BIFs and File Component upload actions in Web Support

The web runtimes now have file uploading capabiltiies finalized.

Bugs

BL-405 BigIntegers cause error: integer number too large

BL-419 Not all unquoted tag attribute values are parsing

Add Your Comment

Recent Entries

Why BoxLang When You Have Kotlin, Groovy, Scala, and more…

Why BoxLang When You Have Kotlin, Groovy, Scala, and more…

As we approach a stable release of BoxLang and our continued marketing reaches more folks, many have asked about its purpose. Why create a new language when the JVM ecosystem already includes established languages like Kotlin, Groovy, and Scala, to name a few.

Luis Majano
Luis Majano
December 18, 2024
ColdBox Free Tip 6 - Using Routing with Wildcard Domains!

ColdBox Free Tip 6 - Using Routing with Wildcard Domains!

ColdBox gives you the flexibility to create domain-specific routes, making it perfect for multi-tenant applications or projects that need to respond differently based on the domain or subdomain being accessed. In this tip, we’ll dive into how to use the withDomain() method to create routes that match specific domains or sub-domains.

Maria Jose Herrera
Maria Jose Herrera
December 18, 2024